package cn.devcat.sso.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import cn.devcat.sso.config.security.filter.DevcatFilterInvocationSecurityMetadataSource;
import cn.devcat.sso.config.security.filter.TokenLoginFilter;
import cn.devcat.sso.config.security.handler.DevcatAccessDecisionManager;
import cn.devcat.sso.config.security.handler.DevcatAccessDeniedHandler;
import cn.devcat.sso.config.security.handler.DevcatAuthenticationEntryPoint;
import cn.devcat.sso.config.security.handler.DevcatLoginSuccessHandler;
import cn.devcat.sso.config.security.handler.DevcatLogoutSuccessHandler;
import lombok.extern.slf4j.Slf4j;

/**
 * Spring Security Config Class
 * 
 * @author huhailong
 *
 */
@Slf4j
@EnableWebSecurity
public class DevcatSecurityConfig {

	@Autowired
	TokenLoginFilter tokenLoginFilter;

	@Autowired
	DevcatFilterInvocationSecurityMetadataSource metadataSource;
	
	@Autowired
	DevcatLoginSuccessHandler devcatLoginSuccessHandler;
	
	@Autowired
	DevcatLogoutSuccessHandler devcatLogoutSuccessHandler;

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.authorizeRequests().anyRequest().authenticated()
				.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
					@Override
					public <O extends FilterSecurityInterceptor> O postProcess(O object) {
						log.info("come in object post processor");
						object.setAccessDecisionManager(new DevcatAccessDecisionManager());
						object.setSecurityMetadataSource(metadataSource);
						return object;
					}
				}).and().apply(CustomDSL.customDsl(devcatLoginSuccessHandler)).and().formLogin().permitAll().and().logout()
				.logoutSuccessHandler(devcatLogoutSuccessHandler).and().exceptionHandling()
				.authenticationEntryPoint(new DevcatAuthenticationEntryPoint()).and().exceptionHandling()
				.accessDeniedHandler(new DevcatAccessDeniedHandler()).and().csrf().disable().cors();
		http.addFilterBefore(tokenLoginFilter, UsernamePasswordAuthenticationFilter.class);
		http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
		return http.build();
	}
}
